package com.hfzy.ihk.web.aliyuncall.biz;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.hfzy.ihk.common.util.string.StringTools;
import com.hfzy.ihk.web.aliyuncall.constant.BLRecordFields;
import com.hfzy.ihk.web.aliyuncall.constant.RedisFields;
import com.hfzy.ihk.web.aliyuncall.constant.RedisKey;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;

/**
 * 将呼叫结果推送到保利-爱家处理逻辑类
 */
@Component
public class PushDataToBLBiz {


    private static final Logger LOG = LoggerFactory.getLogger(PushDataToBLBiz.class);
    @Value("${pushdata.bl.data-url}")
    public String pushDataUrl;

    @Value("${pushdata.bl.record-file-url}")
    public String pushRecordFileUrl;



    @Autowired
    RedisTemplate redisTemplate;

    /**
     * 推送前先把当前的推送记录，如果成功在删除，不然跑job重推
     * @param recordMap
     */

    @Async("pushDataToBlTaskExecutor")
    public void callPushData(Map<String,String> recordMap){
        LOG.info(">>>>>>>>>>>.推送爱家数据map:{}",recordMap.toString());
        pushData(recordMap,false);
    }

    public void jobPushData(Map<String,String> recordMap){
        LOG.info(">>>>>>>>>>>.推送爱家数据1111111map:{}",recordMap.toString());
        pushData(recordMap,true);
    }

    /**
     * 推送前先把当前的推送记录，如果成功在删除，不然跑job重推
     * @param sessionId
     * @param url
     */
    @Async("pushDataToBlTaskExecutor")
    public void callPushRecordUrl(String sessionId,String url){
        pushRecordUrl(sessionId,url,false);
    }

    public void jobPushRecordUrl(String sessionId,String url){
        pushRecordUrl(sessionId,url,true);
    }

    public void pushData(Map<String,String> recordMap,boolean isJob){
        //获取需要推送的数据
        Map<String,String> map = new HashMap<>();
        map.put(BLRecordFields.SESSION_ID,recordMap.get(RedisFields.CALL_HISTORY_SESSION_ID));
        map.put(BLRecordFields.WEBSOCKET_TOKEN,recordMap.get(RedisFields.CALL_HISTORY_MACHINE_FROM));
        map.put(BLRecordFields.CREATE_TIME,recordMap.get(RedisFields.CREATE_TIME));
        map.put(BLRecordFields.MAIN_CALL_PHONE,recordMap.get(RedisFields.CALL_HISTORY_MAIN_CALL_PHONE));
        map.put(BLRecordFields.TARGET_CALL_PHONE,recordMap.get(RedisFields.CALL_HISTORY_TARGET_CALL_PHONE));
        map.put(BLRecordFields.SHOW_NUM,recordMap.get(RedisFields.CALL_HISTORY_SHOW_NUM));
        map.put(BLRecordFields.USER_ID,recordMap.get(RedisFields.CREATE_USER_ID));
        map.put(BLRecordFields.DATA_ID,recordMap.get(RedisFields.CALL_HISTORY_DATA_ID));
        map.put(BLRecordFields.WHERE_FROM,recordMap.get(RedisFields.CALL_HISTORY_WHERE_FROM));
        map.put(BLRecordFields.CUSTOMER_NAME,recordMap.get(RedisFields.CALL_HISTORY_CUSTOMER_NAME)==null?"":recordMap.get(RedisFields.CALL_HISTORY_CUSTOMER_NAME));
        map.put(BLRecordFields.COMMIT_TO,recordMap.get(RedisFields.CALL_HISTORY_COMMIT_TO));
        map.put(BLRecordFields.COMMIT_OK,"true".equals(recordMap.get(RedisFields.CALL_HISTORY_COMMIT_OK))?"1":"0");
        map.put(BLRecordFields.COMMIT_TIME,recordMap.get(RedisFields.CALL_HISTORY_COMMIT_TIME));
        map.put(BLRecordFields.INTERRUPT,recordMap.get(RedisFields.INTERRUPT)==null?"-1":recordMap.get(RedisFields.INTERRUPT));
        map.put(BLRecordFields.INTERRUPT_TIME,recordMap.get(RedisFields.INTERRUPTTIME)==null?"":recordMap.get(RedisFields.INTERRUPTTIME));
        map.put(BLRecordFields.CITY,recordMap.get(RedisFields.CALL_HISTORY_CITY)==null?"":recordMap.get(RedisFields.CALL_HISTORY_CITY));
        map.put(BLRecordFields.CALL_TYPE,recordMap.get(RedisFields.CALL_HISTORY_CALL_TYPE));
        map.put(BLRecordFields.MAIN_CALL_START_TIME,recordMap.get(RedisFields.MAIN_CALL_START_TIME)==null?"":recordMap.get(RedisFields.MAIN_CALL_START_TIME));
        map.put(BLRecordFields.MAIN_CALL_END_TIME,recordMap.get(RedisFields.MAIN_CALL_END_TIME)==null?"":recordMap.get(RedisFields.MAIN_CALL_END_TIME));
        map.put(BLRecordFields.MAIN_CALL_LENGTH,recordMap.get(RedisFields.MAIN_CALL_LENGTH));
        map.put(BLRecordFields.TARGET_CALL_START_TIME,recordMap.get(RedisFields.TARGET_CALL_START_TIME)==null?"":recordMap.get(RedisFields.TARGET_CALL_START_TIME));
        map.put(BLRecordFields.TARGET_CALL_END_TIME,recordMap.get(RedisFields.TARGET_CALL_END_TIME)==null?"":recordMap.get(RedisFields.TARGET_CALL_END_TIME));
        map.put(BLRecordFields.TARGET_CALL_LENGTH,recordMap.get(RedisFields.TARGET_CALL_LENGTH));
        String sessionId = recordMap.get(RedisFields.CALL_HISTORY_SESSION_ID);
        //推送
        try{
          String responstr = JSONObject.toJSONString(map,
                  SerializerFeature.WriteNullStringAsEmpty);
            LOG.info("推送呼叫记录到保利爱家data：{}",responstr);
            Long startTime = System.currentTimeMillis();
            String rs = doPost(pushDataUrl, responstr);
            if(StringTools.isNotempty(rs)) {
                JSONObject rsJson = JSON.parseObject(rs);
                if (rsJson.containsKey("code") && "SUCCESS".equals(rsJson.getString("code"))) {//处理成功
                    LOG.info("推送数据到保利爱家成功，用时:{},rs:{}",(System.currentTimeMillis()-startTime),rs);
                    if(isJob)
                    {
                        removeReids("record",sessionId);
                    }
                } else {//调用失败,不用删redis中的key
                    LOG.error("推送数据到保利爱家失败，失败原因：{}", rsJson.get("code"));
                    setReids("record",sessionId);
                }
            }else{
                LOG.error("推送数据到保利爱家失败，失败原因：responseEntity 为空");
                setReids("record",sessionId);
            }
        }catch (Exception e){//错误，不用删除redis的key
            LOG.error("推送保利错误>> sessionId:{}",recordMap.get(RedisFields.CALL_HISTORY_SESSION_ID),e);
            setReids("record",sessionId);
        }
    }


    public void pushRecordUrl(String sessionId,String url,boolean isJob){
        if(StringTools.isEmpty(sessionId)||StringTools.isEmpty(url)){
            return ;
        }
        Map<String,String> map = new HashMap<>();
        map.put(BLRecordFields.SESSION_ID,sessionId);
        map.put(BLRecordFields.RECORD_FILE_URL,url);
        //推送
        try{
            String responstr = JSONObject.toJSONString(map,
                    SerializerFeature.WriteNullStringAsEmpty);
            LOG.info("推送录音url到保利爱家data：{}",responstr);
            Long startTime = System.currentTimeMillis();
            String rs = doPost(pushRecordFileUrl, responstr);
            if(StringTools.isNotempty(rs)) {
                JSONObject rsJson = JSON.parseObject(rs);
                if (rsJson.containsKey("code") && "SUCCESS".equals(rsJson.getString("code"))) {//处理成功 删除redis中的key
                    LOG.info("推送录音url到保利爱家成功，用时:{},rs:{}",(System.currentTimeMillis()-startTime),rs);
                    if(isJob)
                    {
                        removeReids("url",sessionId);
                    }
                } else {//调用失败,不用删redis中的key
                    LOG.error("推送录音url到保利爱家失败，失败原因：{}", rsJson.get("code"));
                    setReids("url",sessionId);
                }
            }else{
                LOG.error("推送录音url到保利爱家失败，失败原因：responseEntity 为空");
                setReids("url",sessionId);
            }
        }catch (Exception e){//错误，不用删除redis的key
            LOG.error("推送保利错误>> sessionId:{}",sessionId,e);
            setReids("url",sessionId);
        }

    }

    public void setReids(String type,String sessionId){
        try {
            if ("record".equals(type)) {
                redisTemplate.opsForSet().add(RedisKey.PUSH_RECORD_TO_BL_FAILED_SET, sessionId);
            } else if ("url".equals(type)) {
                redisTemplate.opsForSet().add(RedisKey.PUSH_URL_TO_BL_FAILED_SET, sessionId);
            }

        }catch ( Exception e){
            LOG.error(">>>>>>>>将推送保利失败数据保存到redis失败！",e);
        }
    }

    public void removeReids(String type,String sessionId){
        try {
            if ("record".equals(type)) {
                redisTemplate.opsForSet().remove(RedisKey.PUSH_RECORD_TO_BL_FAILED_SET, sessionId);
            } else if ("url".equals(type)) {
                redisTemplate.opsForSet().remove(RedisKey.PUSH_URL_TO_BL_FAILED_SET, sessionId);
            }

        }catch ( Exception e){
            LOG.error(">>>>>>>>将推送保利失败数据保存到redis失败！",e);
        }
    }


    public static void main(String[] args) {
        String url = "http://113.108.206.98:8880/sales-web/rest/cloudCall/log";
        String message="{\"targetCallEndTime\":\"20181030160011000\",\"mainCallPhone\":\"13418035053\",\"mainCallStartTime\":\"20181030155948000\",\"city\":\"-1\",\"whereFrom\":\"11\",\"commitOk\":\"true\",\"sessionId\":\"AWbD-HDz5veBX6NsxFCk\",\"commitTo\":\"11\",\"userId\":\"11\",\"customerName\":\"张三\",\"callType\":\"0\",\"token\":\"testCallMachine_1540884354501\",\"showNum\":\"057128204523\",\"mainCallEndTime\":\"20181030160011000\",\"mainCallLength\":\"23\",\"dataId\":\"933\",\"createTime\":\"20181030155936651\",\"commitTime\":\"20181030155936651\",\"targetCallPhone\":\"13632446454\",\"targetCallStartTime\":\"20181030160001000\",\"targetCallLength\":\"10\"} ";
        PushDataToBLBiz pushDataToBLBiz = new PushDataToBLBiz();

        try {
            pushDataToBLBiz.doPost(url,message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 有异常直接抛出，当做没推成功
     * @param url
     * @param message
     * @return
     * @throws Exception
     */
    private String doPost(String url, String message) throws Exception{
        LOG.info(">>>>>>>>>url：{}",url);
        String rs="";
        CloseableHttpClient client = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        httpPost.setHeader("Content-type", "application/json; charset=utf-8");
        httpPost.setHeader("Accept", "application/json");
        httpPost.setHeader("Access-Token","be703a7741b941aabd17839e25f5ab0d");
        StringEntity requestEntity = new StringEntity(message, Charset.forName("UTF-8"));
        httpPost.setEntity(requestEntity);

        LOG.info("request >> {}", EntityUtils.toString(requestEntity, Charset.forName("UTF-8")));
        CloseableHttpResponse response = client.execute(httpPost);
        HttpEntity responseEntity = response.getEntity();
        try {
            if (responseEntity != null) {
                rs= EntityUtils.toString(responseEntity, Charset.forName("UTF-8"));
                LOG.info("response >> {}",rs);

            } else {
                LOG.info("response is null ");
            }
        }catch (Exception e){
            throw new Exception();
        }finally {
             response.close();
             client.close();
             return rs;

        }





    }

}
